// File Name: rs485_task.c
// Author: kukukukuku~
// Date: 2024-07-17

#include "./User/ADC/inc/adc_ctrl.h"
#include "./User/Flash/inc/flash_task.h"
#include "./User/Key/inc/key_ctrl.h"
#include "./User/LED/inc/led_ctrl.h"
#include "./User/OLED/inc/oled_ctrl.h"
#include "./User/RS485/inc/rs485_task.h"
#include "./User/Step_Motor/inc/step_motor_ctrl.h"
#include "./User/Sys/inc/init.h"
#include "./User/WS2812B/inc/ws2812b_ctrl.h"

TaskHandle_t taskHandleRs485;   //RS485任务句柄

/**
 * @brief   RS485任务
 * @param   arg:    任务参数
 * @retval  None
 * @note    None
*/
void task_rs485(void *arg)
{
    usart_init(RS485_USART, rs485UsartBaudRate, RS485_USART_DATA, RS485_USART_STOP);
    usart_enable(RS485_USART, TRUE);
    
    while(1)
    {
        rs485_data_handle();
        
        //给予信号量，等待数据保存完成
        if(rs485SaveFlag == 1)
        {
            xSemaphoreGive(semaphBinFlash);
        }
        //获取保存结果，发送响应
        else if(rs485SaveFlag == 2 || rs485SaveFlag == 3)
        {
            rs485_modbus_write_single_reg_response(RS485_REG_SAVE, rs485SaveFlag - 2, 0, 0xFFFF);
            rs485SaveFlag = 0;
        }
        
        //系统复位
        if(rs485RebootFlag)
        {
            rs485RebootFlag = 0;
            nvic_system_reset();
        }
        
        //擦除数据保存的扇区
        if(rs485ResetFlag == 1)
        {
            flash_unlock();
            flash_erase_sectors(FLASH_ADDR_DATA_START) ?\
            (rs485ResetFlag = 3) :\
            (rs485ResetFlag = 2);
            flash_lock();
        }
        
        //获取擦除结果，发送响应，复位系统重新初始化
        if(rs485ResetFlag == 2 || rs485ResetFlag == 3)
        {
            rs485_modbus_write_single_reg_response(RS485_REG_RESET, rs485ResetFlag - 2, 0, 0xFFFF);
            rs485ResetFlag = 0;
            nvic_system_reset();
        }
        
        //主动模式
        if(rs485Mode == 0)
        {
            rs485_modbus_read_single_reg_response(RS485_REG_MODBUS_ACTIVE_INTERVAL, rs485ActiveInterval);
            vTaskDelay(10);
            
            rs485_modbus_read_single_reg_response(RS485_REG_KEY_CLICK_BEEP, keyClickBeep);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_KEY_LONG_BEEP, keyLongBeep);
            vTaskDelay(10);
            
            rs485_modbus_read_single_reg_response(RS485_REG_LED1_MODE, led1.mode);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_LED2_MODE, led2.mode);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_LED1_BREATH_STEP, led1.breathStep);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_LED2_BREATH_STEP, led2.breathStep);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_LED1_BLINK_FREQ, led1.blinkNum);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_LED2_BLINK_FREQ, led2.blinkNum);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_LED1_SWITCH, led1.state);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_LED2_SWITCH, led2.state);
            vTaskDelay(10);
            
            rs485_modbus_read_single_reg_response(RS485_REG_OLED_DIR, oledDir);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_OLED_LIGHT, oledLightLevel);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_OLED_CURSOR, oledCursorStyle);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_OLED_REFRESH_MS, oledMainPageRefreshInterval);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_OLED_MENU_NUMBER, oledMenuNumberFlag);
            vTaskDelay(10);
            
            rs485_modbus_read_single_reg_response(RS485_REG_STEP_MOTOR_STATE, stepMotorState);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_STEP_MOTOR_MODE, stepMotorMode);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_STEP_MOTOR_SPD, stepMotorSpd);
            vTaskDelay(10);
            
            rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_MODE, ws2812bMode);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_STOP_R, ws2812bStopRed);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_STOP_G, ws2812bStopGreen);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_STOP_B, ws2812bStopBlue);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_CW_MODE, ws2812bCwMode);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_CW_R, ws2812bCwRed);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_CW_G, ws2812bCwGreen);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_CW_B, ws2812bCwBlue);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_CCW_MODE, ws2812bCcwMode);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_CCW_R, ws2812bCcwRed);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_CCW_G, ws2812bCcwGreen);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_WS2812B_CCW_B, ws2812bCcwBlue);
            vTaskDelay(10);
            
            rs485_modbus_read_single_reg_response(RS485_REG_TEMPERATURE, (uint16_t)((uint32_t)temperature) << 8 | ((uint32_t)(temperature * 100) % 100));
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_V_REF, (uint16_t)((uint32_t)vRef) << 8 | ((uint32_t)(vRef * 100) % 100));
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_VERSION_H, VERSION_MAIN);
            vTaskDelay(10);
            rs485_modbus_read_single_reg_response(RS485_REG_VERSION_L, VERSION_SECOND << 8 | VERSION_PHASE);
            vTaskDelay(10);
            
            vTaskDelay(rs485ActiveInterval);
        }
        //被动模式
        else
        {
            vTaskDelay(10);
        }
    }
}
